package Game;

import Game.Player.PlayerID;



public class Game {
	
	private Player.PlayerID[][] field;
	private FieldState[][] fieldStates;
	private Player.PlayerID currentPlayer;
	private FieldState state;
	
	public Game(Player.PlayerID start) {
		this.currentPlayer = start;
		state = FieldState.selectable;
		field = new Player.PlayerID[8][8];
		fieldStates = new FieldState[2][2];
		for (int x=0; x < fieldStates.length; x++) {
			for (int y=0; y < fieldStates[x].length; y++) {
				fieldStates[x][y]= FieldState.selectable;
			}
		}
	}
	
	public boolean updateField(Player.PlayerID id, int x, int y) {
		if (state == FieldState.selectable && id == currentPlayer && fieldStates[x/3][y/3] == FieldState.selectable && field[x][y]==null) {//ToDo: Spielabbrechbedingung
			field[x][y]=id;
			updateFieldStates(x, y);
			updateState();
			currentPlayer = currentPlayer == PlayerID.you ? PlayerID.opponent : PlayerID.you;
			return true;
		} else {
			return false;
		}
	}
	
	private void updateFieldStates(int x, int y) {
		checkWin(x / 3, y / 3);
		if (fieldStates[x % 3][y % 3] == FieldState.selectable) {
			for (int xx=0; xx < fieldStates.length; xx++) {
				for (int yy=0; yy < fieldStates[xx].length; yy++) {
					if (fieldStates[xx][yy] == FieldState.selectable) {
						fieldStates[xx][yy] = null;
					}
				}
			}
			fieldStates[x % 3][y % 3] = FieldState.selectable;
		}
	}
	
	private void checkWin(int x, int y) {
		x *= 3;
		y *= 3;
		for (int i = 0; i < 3 ; i++) {
			if (field[x + i][y] == field[x + i][y + 1] && field[x + i][y] == field[x + i][y + 2]) {
				if (field[x + i][y] == PlayerID.you) {
					fieldStates[x / 3][y / 3] = FieldState.won;
					return;
				} else {
					fieldStates[x / 3][y / 3] = FieldState.lost;
					return;
				}
			}
			if (field[x][y + i] == field[x + 1][y + i] && field[x][y + i] == field[x + 2][y + i]) {
				if (field[x][y + i] == PlayerID.you) {
					fieldStates[x / 3][y / 3] = FieldState.won;
					return;
				} else {
					fieldStates[x / 3][y / 3] = FieldState.lost;
					return;
				}
			}
		}
		if (field[x][y] == field[x + 1][y + 1] && field[x][y] == field[x + 2][y + 2]) {
			if (field[x][y] == PlayerID.you) {
				fieldStates[x / 3][y / 3] = FieldState.won;
				return;
			} else {
				fieldStates[x / 3][y / 3] = FieldState.lost;
				return;
			}
		}
		if (field[x + 2][y] == field[x + 1][y + 1] && field[x + 2][y] == field[x][y + 2]) {
			if (field[x][y] == PlayerID.you) {
				fieldStates[x / 3][y / 3] = FieldState.won;
				return;
			} else {
				fieldStates[x / 3][y / 3] = FieldState.lost;
				return;
			}
		}
		for (int xx=0; xx < fieldStates.length; xx++) {
			for (int yy=0; yy < fieldStates[xx].length; yy++) {
				if (field[x + xx][y + yy] == null) {
					fieldStates[x / 3][y / 3] = FieldState.selectable;
					return;
				}
			}
		}
		fieldStates[x / 3][y / 3] = FieldState.tie;
	}
	
	private void updateState() {
		for (int i = 0; i < 3 ; i++) {
			if (fieldStates[i][0] == fieldStates[i][1] && fieldStates[i][0] == fieldStates[i][2]) {
				if (fieldStates[i][0] == FieldState.won) {
					state = FieldState.won;
					return;
				} else {
					state  = FieldState.lost;
					return;
				}
			}
			if (fieldStates[0][i] == fieldStates[1][i] && fieldStates[0][i] == fieldStates[2][i]) {
				if (fieldStates[0][i] == FieldState.won) {
					state = FieldState.won;
					return;
				} else {
					state = FieldState.lost;
					return;
				}
			}
		}
		if (fieldStates[0][0] == fieldStates[1][1] && fieldStates[0][0] == fieldStates[2][2]) {
			if (fieldStates[0][0] == FieldState.won) {
				state = FieldState.won;
				return;
			} else {
				state = FieldState.lost;
				return;
			}
		}
		if (fieldStates[2][0] == fieldStates[1][1] && fieldStates[2][0] == fieldStates[0][2]) {
			if (fieldStates[0][0] == FieldState.won) {
				state = FieldState.won;
				return;
			} else {
				state = FieldState.lost;
				return;
			}
		}
		for (int xx=0; xx < fieldStates.length; xx++) {
			for (int yy=0; yy < fieldStates[xx].length; yy++) {
				if (fieldStates[xx][yy] == null) {
					state = FieldState.selectable;
					return;
				}
			}
		}
		state = FieldState.tie;
	}
	
	public Player.PlayerID getCurrentPlayer() {
		return currentPlayer;
	}
	
	public Player.PlayerID getPlayer(int x, int y) {
		return field[x][y];
	}

	public FieldState getFieldState(int x, int y) {
		return fieldStates[x / 3][y / 3];
	}
	
	public FieldState getState() {
		return state;
	}
	
	public PlayerID[][] getField() {
		return field;
	}
	
	public enum FieldState {
		
		selectable(0), won(1), lost(2), tie(3);
		
		public final int state;
		
		private FieldState(int state) {
			this.state = state;
		}
		
	}
	
}
